package com.lyh.system.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.lyh.common.core.domain.entity.SysUser;
import com.lyh.common.enums.*;
import com.lyh.common.exception.user.UserNotExistsException;
import com.lyh.common.utils.CommonUtils;
import com.lyh.common.utils.DateUtils;
import com.lyh.common.utils.SecurityUtils;
import com.lyh.system.biz.IPayBiz;
import com.lyh.system.domain.OperationInfo;
import com.lyh.system.domain.RechargeRecord;
import com.lyh.system.domain.SysMemberUser;
import com.lyh.system.domain.vo.AnalogRechargeVo;
import com.lyh.system.mapper.OperationInfoMapper;
import com.lyh.system.mapper.RechargeRecordMapper;
import com.lyh.system.mapper.SysUserMapper;
import com.lyh.system.service.ISysMemberUserService;
import com.lyh.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lyh.system.mapper.AssetMapper;
import com.lyh.system.domain.Asset;
import com.lyh.system.service.IAssetService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 资产Service业务层处理
 *
 * @author ruoyi
 * @date 2023-04-27
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AssetServiceImpl implements IAssetService {
    @Autowired
    private AssetMapper assetMapper;

    @Autowired
    private OperationInfoMapper operationInfoMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RechargeRecordMapper rechargeRecordMapper;

    @Autowired
    private IPayBiz payBiz;

    /**
     * 查询资产
     *
     * @param id 资产主键
     * @return 资产
     */
    @Override
    public Asset selectAssetById(Long id) {
        return assetMapper.selectAssetById(id);
    }

    /**
     * 查询资产列表
     *
     * @param asset 资产
     * @return 资产
     */
    @Override
    public List<Asset> selectAssetList(Asset asset) {
        return assetMapper.selectAssetList(asset);
    }

    /**
     * 新增资产
     *
     * @param asset 资产
     * @return 结果
     */
    @Override
    public int insertAsset(Asset asset) {
        asset.setCreateTime(DateUtils.getNowDate());
        return assetMapper.insertAsset(asset);
    }

    /**
     * 修改资产
     *
     * @param asset 资产
     * @return 结果
     */
    @Override
    public int updateAsset(Asset asset) {
        asset.setUpdateTime(DateUtils.getNowDate());
        return assetMapper.updateAsset(asset);
    }

    /**
     * 批量删除资产
     *
     * @param ids 需要删除的资产主键
     * @return 结果
     */
    @Override
    public int deleteAssetByIds(Long[] ids) {
        return assetMapper.deleteAssetByIds(ids);
    }

    /**
     * 删除资产信息
     *
     * @param id 资产主键
     * @return 结果
     */
    @Override
    public int deleteAssetById(Long id) {
        return assetMapper.deleteAssetById(id);
    }

    @Override
    public Asset selectAssetByMemberId(Long memberId) {
        return assetMapper.selectAssetByMemberId(memberId);
    }

    @Override
    public synchronized String send(Long receiveMemberId, BigDecimal num) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (num.compareTo(new BigDecimal(0)) <= 0) {
            throw new RuntimeException("无效的数量！");
        }

        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", receiveMemberId);
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper);

        Asset receiveAsset = assetMapper.selectAssetByUserId(sysUser.getUserId());
        Asset sendAsset = assetMapper.selectAssetByUserId(user.getUserId());

        if (sendAsset == null || receiveAsset == null) {
            throw new RuntimeException("会员id无效，用户不存在！");
        }


        if (sendAsset.getAssetEvidenceNum() != null && receiveAsset.getAssetEvidenceNum() != null) {
            BigDecimal subtract = sendAsset.getAssetEvidenceNum().subtract(num);
            if (subtract.compareTo(new BigDecimal(0.00)) < 0) {
                throw new RuntimeException("您的余额不足，无法转让!");
            } else {
                BigDecimal add = receiveAsset.getAssetEvidenceNum().add(num);
                sendAsset.setAssetEvidenceNum(subtract);
                receiveAsset.setAssetEvidenceNum(add);
                assetMapper.updateById(sendAsset);
                assetMapper.updateById(receiveAsset);

                OperationInfo oi = new OperationInfo();
                oi.setUserId(user.getUserId());
                oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                oi.setStatus(OperationStatusEnum.EXPENSE.name());
                oi.setOperationTime(new Date());
                oi.setPrice(num);
                oi.setOrigin(OperationOriginEnum.ASSET_EVIDENCE_TRANSFER_OUT.name());
                operationInfoMapper.insert(oi);

                OperationInfo oi1 = new OperationInfo();
                oi1.setUserId(sysUser.getUserId());
                oi1.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                oi1.setStatus(OperationStatusEnum.INCOME.name());
                oi1.setOperationTime(new Date());
                oi1.setPrice(num);
                oi1.setOrigin(OperationOriginEnum.ASSET_EVIDENCE_RECEIVE.name());
                operationInfoMapper.insert(oi1);
            }
        }
        return "转让成功！";
    }

    /**
     * 消费券转让
     *
     * @param receiveMemberId
     * @param num
     * @return
     */
    @Override
    public synchronized String consumerSend(Long receiveMemberId, BigDecimal num) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (num.compareTo(new BigDecimal(0)) <= 0) {
            throw new RuntimeException("无效的数量！");
        }
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", receiveMemberId);
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper);

        Asset receiveAsset = assetMapper.selectAssetByUserId(sysUser.getUserId());
        Asset sendAsset = assetMapper.selectAssetByUserId(user.getUserId());

        if (sendAsset == null || receiveAsset == null) {
            throw new UserNotExistsException();
        }
        if (sendAsset.getConsumerCouponNum() != null && receiveAsset.getConsumerCouponNum() != null) {
            BigDecimal subtract = sendAsset.getConsumerCouponNum().subtract(num);
            if (subtract.compareTo(new BigDecimal(0)) < 0) {
                throw new RuntimeException("您的余额不足，无法转让!");
            } else {
                sendAsset.setConsumerCouponNum(subtract);
                receiveAsset.setConsumerCouponNum(receiveAsset.getConsumerCouponNum().add(num));
                assetMapper.updateById(sendAsset);
                assetMapper.updateById(receiveAsset);

                OperationInfo oi = new OperationInfo();
                oi.setUserId(user.getUserId());
                oi.setType(OperationTypeEnum.CONSUMER_COUPON.name());
                oi.setStatus(OperationStatusEnum.EXPENSE.name());
                oi.setOperationTime(new Date());
                oi.setPrice(num);
                oi.setOrigin(OperationOriginEnum.CONSUMER_COUPON_TRANSFER_OUT.name());
                operationInfoMapper.insert(oi);

                OperationInfo oi1 = new OperationInfo();
                oi1.setUserId(sysUser.getUserId());
                oi1.setType(OperationTypeEnum.CONSUMER_COUPON.name());
                oi1.setStatus(OperationStatusEnum.INCOME.name());
                oi1.setOperationTime(new Date());
                oi1.setPrice(num);
                oi1.setOrigin(OperationOriginEnum.CONSUMER_COUPON_RECEIVE.name());
                operationInfoMapper.insert(oi1);
            }
        }
        return "转让成功！";
    }

    @Override
    public synchronized String consumerRecharge(Integer num) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Asset asset = assetMapper.selectAssetByUserId(user.getUserId());
        if (asset == null) {
            throw new UserNotExistsException();
        }
        if (num == null) {
            throw new RuntimeException("未填写充值消费券数量");
        }
        if (asset.getAccountBalance() != null) {
            if (asset.getAccountBalance().compareTo(new BigDecimal(num)) < 0) {
                throw new RuntimeException("余额不足，请及时充值");
            }
            BigDecimal subtract = asset.getAccountBalance().subtract(new BigDecimal(num));
            asset.setAccountBalance(subtract);
            asset.setConsumerCouponNum(asset.getConsumerCouponNum().add(new BigDecimal(num)));
            assetMapper.updateById(asset);
        }
        return "充值成功！";
    }

    /**
     * 门店积分 转让
     *
     * @param receiveMemberId
     * @param num
     * @return
     */
    @Override
    public String integralSend(Long receiveMemberId, Integer num) {

        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!user.getIsMstore()) {
            throw new RuntimeException("无法转让，您不是门店长，请先升级为门店长在进行转让！");
        }
        if (num <= 0) {
            throw new RuntimeException("无效的数量！");
        }
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", receiveMemberId);
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper);

        Asset receiveAsset = assetMapper.selectAssetByUserId(sysUser.getUserId());
        Asset sendAsset = assetMapper.selectAssetByUserId(user.getUserId());

        if (sendAsset == null || receiveAsset == null) {
            throw new UserNotExistsException();
        }
        if (sendAsset.getIntegral() != null && receiveAsset.getIntegral() != null) {
            long result = sendAsset.getIntegral() - num;
            if (result < 0) {
                throw new RuntimeException("您的余额不足，无法转让!");
            } else {
                sendAsset.setIntegral(result);
                receiveAsset.setIntegral(receiveAsset.getIntegral() + num);
                assetMapper.updateById(sendAsset);
                assetMapper.updateById(receiveAsset);
            }
        }
        return "转让成功！";
    }


    /**
     * 模拟充值
     *
     * @param arv
     */
    @Override
    public void analogRecharge(AnalogRechargeVo arv) {
        if (arv.getAmount().compareTo(new BigDecimal(0)) <= 0) {
            throw new RuntimeException("充值金额有误！");
        }
        SysUser user = SecurityUtils.getLoginUser().getUser();
        //添加收支记录
        OperationInfo oi = new OperationInfo();
        oi.setUserId(user.getUserId());
        Asset asset = assetMapper.selectAssetByUserId(user.getUserId());
        if (OperationTypeEnum.CASH.name().equals(arv.getType())) {
            asset.setAccountBalance(asset.getAccountBalance().add(arv.getAmount()));
            oi.setType(OperationTypeEnum.CASH.name());
        } else if (OperationTypeEnum.ASSET_EVIDENCE.name().equals(arv.getType())) {
            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(arv.getAmount()));
            oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
        } else if (OperationTypeEnum.CONSUMER_COUPON.name().equals(arv.getType())) {
            asset.setConsumerCouponNum(asset.getConsumerCouponNum().add(arv.getAmount()));
            oi.setType(OperationTypeEnum.CONSUMER_COUPON.name());
        }
        oi.setStatus(OperationStatusEnum.INCOME.name());
        oi.setOperationTime(new Date());
        oi.setPrice(arv.getAmount());
        oi.setOrigin(OperationOriginEnum.RECHARGE.name());
        operationInfoMapper.insert(oi);
        assetMapper.updateById(asset);
    }


    @Transactional
    @Override
    public String newAnalogRecharge(AnalogRechargeVo arv) {
        if (arv.getAmount().compareTo(new BigDecimal(0)) <= 0) {
            throw new RuntimeException("充值金额有误！");
        }
        SysUser user = SecurityUtils.getLoginUser().getUser();
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setUserId(user.getUserId());
        rechargeRecord.setPaymentMethod(arv.getPaymentMethod());
        rechargeRecord.setOrderId("Rec" + CommonUtils.getRandom());
        rechargeRecord.setPaymentStatus(RechargeStatusEnum.WAIT.name());
        rechargeRecord.setRechargeAmount(arv.getAmount());
        rechargeRecord.setRechargeTime(new Date());
        rechargeRecord.setRechargeType(arv.getType());
        rechargeRecord.setId(IdWorker.getId());
        rechargeRecordMapper.insertRechargeRecord(rechargeRecord);
        String returnStr = payBiz.zfbRechargePay(rechargeRecord);
        return returnStr;

    }

    @Override
    public void addOperationInfo(Long userId, String type, String status, String origin, BigDecimal price) {
        if (price.compareTo(new BigDecimal(0)) > 0) {
            OperationInfo info = new OperationInfo();
            info.setUserId(userId);
            info.setOperationTime(new Date());
            info.setOrigin(origin);
            info.setPrice(price);
            info.setType(type);
            info.setStatus(status);
            operationInfoMapper.insert(info);
        }
    }
}

